#ifndef GAMEMASTER_H
#define GAMEMASTER_H
#include "card.h"
#include "Hand.h"
#include "Player.h"
#include "game.h"
#include <QObject>

class Player;
class Server;

class Client;
class game;

class GameMaster : QObject
{
    private:
        int scores[4];
        //int *contract;

        //Network network;
        Player *players[4];
        int TrickWins[4];
        int gameWinners[3];

        bool helperShuffle(int size,int random,int ids[]);
        void initializeDeck();
        int validateHelper(string b);
        int validateHelper2(string b);
        int *idShuffled; //array of shuffled ids
        void determinGameWinner();
        string lastBidUsername;

        Server *server;
        QThread *rootServerThread;

    public:
        GameMaster(QObject *parent = 0);
        GameMaster(game* f);
        game* gameGui;
        QString getServerIP();
        ~GameMaster();
        void shuffle();
        /*!
         * \brief shuffle: Deals the shuffled deck of cards to players and assigns hand to each of the players.
         */
        void deal();
        /*!
         * \brief redeal: No bid has been selected and 4 consecutive passes have been detected deal() function is called again.
         */
        void redeal();

        /*!
         * \brief highBid: assigns the highest bid made by each of the players to the respective player objects.
         * \param b: higest bid of the player
         * \param pos:  player index representing the player index object.
         */
        void highBid(string b,int pos);
        /*!
         * \brief validateBid: validates whether the recieved bid has a greater value than the previous bid.
         * \param bids: stores previous validated bids for comparison purposes.
         * \param b: contains the string with only the current bid.
         * \param a: contains the string with the current bid and action.
         * \param count: contains the last index of the bids[] array.
         * \return : boolean value representing whether bid is valid or not.
         */
        bool validateBid(string bids[],string b,string a, int count);
        /*!
         * \brief UpdateTrickWinner: The winner of  each trick is updated in the trickWins array assosiated with its respective player index.
         */
        void UpdateTrickWinner();

        string determineWinner();
        /*!
         * \brief validateMove: Checks whether the card/ move selected/made by player is valid accorinding the the leadSuit in the current trick
         * \param leadSuit: character of the current Lead suit of the trick
         * \param h: The move/card that needs to be validated.
         * \param pos: The index representing the player that has made the move.
         * \return boolean value repreasenting whether move is valid or not.
         */
        bool validateMove(char leadSuit,Card h,int pos);
        /*!
         * \brief determineScore: According to the TrickWins, contract and bridge conditions the scores array is updated.
         */
        void determineScore();

        void print();
        /*!
         * \brief _cards: pointer to the card.
         */
        Card *_cards;       // pointer to card
        /*!
         * \brief _hand: pointer to hand.
         */
        Hand *_hand;
        /*!
         * \brief deck: deck of cards used during the game.
         */
        list <Card> deck;
        /*!
         * \brief trick: pointer to trick
         */
        Hand *trick;  // to store trick =4 cards while playing
        /*!
         * \brief sendBid: sends current bid to the player after validation of the bid.
         */
        void sendBid(QStringList);
        /*!
         * \brief curr_player: index of the current player a function will execute with. This is for getting or recieving messages to the next player.
         */
        int curr_player;
        /*!
         * \brief ack_playerCounter: index that keeps track of the number of players that have already send back an ack flag.
         */
        int ack_playerCounter;
        /*!
         * \brief ack_cards: acknowledgement that the player has recieved a card.
         */
        void ack_cards();
        /*!
         * \brief ack_startBidding: acknowledgemnt from players showing that bidding has started.
         */
        void ack_startBidding();
        /*!
         * \brief ack_startDealing: acknowledgemnt from players showing that dealing has started.
         */
        void ack_startDealing();
        /*!
         * \brief startSendHand: Starts sending hand phase to all the players.
         */
        void startSendHand();
        /*!
         * \brief ack_sendHand: acknowledgemnt from players showing that send hand has started.
         */
        void ack_sendHand();
        /*!
         * \brief startDealing: Starts the dealing phase.
         */
        void startDealing();
        /*!
         * \brief startBidding: Starts the bidding phase.
         */
        void startBidding();
        /*!
         * \brief bidding: recieves bid from the GUI form.
         */
		 void bidding();
        /*!
		
                 * \brief startSendBid: informs the players about the last bid made
                 */
                void startSendBid();
                /*!
                 * \brief ack_sendBid: player acknowledges that he received the bid that was made
                 */
                void ack_sendBid();
                QStringList lastBid;
                QStringList highestBid;
                int passCount;
                /*!
                 * \brief startRedealing: Informs the player that the redealing phase  has started, player must acknowlege
                 */
                void startRedealing();
                /*!
                 * \brief ack_startRedealing: player should acknowledge that he receives the redealing phase
                 */
                void ack_startRedealing();
                /*!
                 * \brief startSendContract: Sends the contract out to th e players
                 */
                void startSendContract();
                /*!
                 * \brief ack_sendContract: Player shold acknowledge that he received the contract
                 */
                void ack_sendContract();
                /*!
                 * \brief startDummy signals the players that the dummy phase was entered, player must acknowledge
                 */
                void startDummy();
                /*!
                 * \brief ack_startDummy: player should acknowledge that he received the dummy phase message
                 */
                void ack_startDummy();
                /*!
                 * \brief startSendDummyId: send dummy ID to all players
                 */
                void startSendDummyId();
                /*!
                 * \brief ack_startSendDummyId: player should acknowledge that he received the dummy ID
                 */
                void ack_startSendDummyId();
                string dummyId;
                void startSendDummyHand();
                /*!
                 * \brief ack_startSendDummyHand: player should acknowledge that he received the dummy hand
                 */
                void ack_startSendDummyHand();
                Hand dummyHand;
                /*!
                 * \brief startGame: informs the player about the beginning of the playing phase, player must acknowledge
                 */
                void startGame();
                /*!
                 * \brief ack_startGame: player acknowledges that he has received the game start message
                 */
                void ack_startGame();
                /*!
                 * \brief startSendGameUpdate: sends the game update message to the player, player should acknowledge
                 */
                void startSendGameUpdate();
                /*!
                 * \brief ack_startSendGameUpdate: sends the phase update message to players
                 */
                void ack_startSendGameUpdate();
                int numTricks;
                int numDeals;
                int numGames;
                /*!
                 * \brief startPlaying :signals the begging of the play phase
                 */
                void startPlaying();

                void ack_getMove();
                /*!
                 * \brief startSendMove: signals when to start sending a move
                 */
                void startSendMove();
                /*!
                 * \brief ack_sendMove: acknowledges a move sent and prepares to ask the next player for a move
                 */
                void ack_sendMove();
                /*!
                 * \brief startUpdateTrickWinner: sends the trick winner update
                 */
                void startUpdateTrickWinner();
                /*!
                 * \brief ack_startUpdateTrickWinner: sends the update about the trick winner
                 */
                void ack_startUpdateTrickWinner();
                int lastTrickWinner;
                /*!
                 * \brief startUpdateScore: send the score update to all players
                 */
                void startUpdateScore();
                /*!
                 * \brief ack_startUpdateScore: acknowledges the score update message sent
                 */
                void ack_startUpdateScore();
                char leadSuit;
                /*!
                 * \brief sendMove send a move to be validated
                 * \param c : a card of the player's move
                 */
                void sendMove(Card c);
                int firstPlayer;
                int count;
                /*!
                 * \brief startSendWinner: is called to signal when to send the score update messages to all players
                 */
                void startSendWinner();
                /*!
                 * \brief ack_startSendWinner: acknowledges the send winner messages
                 */
                void ack_startSendWinner();
};

#endif // GAMEMASTER_H
